package com.ktgj.pay.payUtil;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ktgj.common.core.utils.HttpClientUtil;
import com.ktgj.pay.controller.UnionPayController;
import com.ktgj.pay.domain.BillPayment;
import com.ktgj.pay.domain.PaymentCallbackVo;
import com.ktgj.pay.domain.UnionPayQRCodeRequest;
import com.ktgj.pay.domain.UnionPayQRCodeResponse;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.web.bind.annotation.PostMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.SortedMap;
import java.util.TreeMap;

public class UnionPayQRCodeUtil
{
    //测试环境接口地址
//    private static String url = "https://qr-test2.chinaums.com/netpay-route-server/api/";
    //生产环境接口地址
    private static String url = "https://qr.chinaums.com/netpay-route-server/api/";

//    //回调测试地址
//    private String callback = "http://localhost:9307/unionPay/paymentCallback";

    /**
     * 银联二维码获取
     * */
    public static UnionPayQRCodeResponse unionPayQRCodePay(UnionPayQRCodeRequest unionPayQRCodeRequest)
    {
        unionPayQRCodeRequest.setMsgType("bills.getQRCode");
        fillQRCodeInfo(unionPayQRCodeRequest);
        String sign = "billDate=" + unionPayQRCodeRequest.getBillDate();
        sign = sign + "&billNo=" + unionPayQRCodeRequest.getBillNo();
//        sign = sign + "&expireTime=" + unionPayQRCodeRequest.getExpireTime();
        sign = sign + "&instMid=" + unionPayQRCodeRequest.getInstMid();
        sign = sign + "&mid=" + unionPayQRCodeRequest.getMid();
        sign = sign + "&msgSrc=" + unionPayQRCodeRequest.getMsgSrc();
        sign = sign + "&msgType=" + unionPayQRCodeRequest.getMsgType();
        sign = sign + "&notifyUrl=" + unionPayQRCodeRequest.getNotifyUrl();
        sign = sign + "&requestTimestamp=" + unionPayQRCodeRequest.getRequestTimestamp();
        sign = sign + "&signType=" + unionPayQRCodeRequest.getSignType();
        sign = sign + "&tid=" + unionPayQRCodeRequest.getTid();
        sign = sign + "&totalAmount=" + unionPayQRCodeRequest.getTotalAmount();
        sign = sign + "8Jj7h5S7eXyC4Y48S7xC2eWbxkdtmaD2d3xa68z7pTekE8Wz";

        String sha = DigestUtils.md5Hex(sign);
        unionPayQRCodeRequest.setSign(sha);
        SortedMap<String, Object> params = new TreeMap<>();
        params.put("msgType", unionPayQRCodeRequest.getMsgType());
        params.put("billNo", unionPayQRCodeRequest.getBillNo());
        params.put("msgSrc", unionPayQRCodeRequest.getMsgSrc());
        params.put("signType", unionPayQRCodeRequest.getSignType());
        params.put("mid", unionPayQRCodeRequest.getMid());
        params.put("tid", unionPayQRCodeRequest.getTid());
        params.put("instMid", unionPayQRCodeRequest.getInstMid());
        params.put("totalAmount", unionPayQRCodeRequest.getTotalAmount());
        params.put("requestTimestamp", unionPayQRCodeRequest.getRequestTimestamp());
        params.put("billDate", unionPayQRCodeRequest.getBillDate());
        params.put("sign", unionPayQRCodeRequest.getSign());
//        params.put("expireTime", unionPayQRCodeRequest.getExpireTime());
        params.put("notifyUrl", unionPayQRCodeRequest.getNotifyUrl());
        String postJson = HttpClientUtil.doPostJson(url, JSON.toJSONString(params));
        UnionPayQRCodeResponse unionPayQRCodeResponse = JSON.parseObject(postJson, UnionPayQRCodeResponse.class);
        return unionPayQRCodeResponse;
    }

    /**
     * 银联二维码支付回调
     * */
    @PostMapping("/paymentCallback")
    public String paymentCallback(HttpServletResponse response, HttpServletRequest request){
        PaymentCallbackVo paymentCallbackVo = new PaymentCallbackVo();
        String parameter = request.getParameter("billPayment");
        BillPayment parseObject = JSONObject.parseObject(parameter, BillPayment.class);
        paymentCallbackVo.setBillPayment(parseObject);
        paymentCallbackVo.setMid(request.getParameter("mid"));//商户号
        paymentCallbackVo.setTid(request.getParameter("tid"));//终端号
        paymentCallbackVo.setInstMid(request.getParameter("instMid"));//业务类型
        paymentCallbackVo.setBillNo(request.getParameter("billNo"));//账单号
        paymentCallbackVo.setBillQRCode(request.getParameter("billQRCode"));//账单二维码
        paymentCallbackVo.setBillStatus(request.getParameter("billStatus"));//账单状态
        paymentCallbackVo.setBillDesc(request.getParameter("billDesc"));//账单描述
        paymentCallbackVo.setMemberId(request.getParameter("memberId"));//会员号
        paymentCallbackVo.setCounterNo(request.getParameter("counterNo"));//桌号、柜台号、房间号
        paymentCallbackVo.setMerName(request.getParameter("merName"));//商户名称
        paymentCallbackVo.setMemo(request.getParameter("memo"));//付款附言
        paymentCallbackVo.setNotifyId(request.getParameter("notifyId"));//支付通知ID
        paymentCallbackVo.setSecureStatus(request.getParameter("secureStatus"));//担保状态
        paymentCallbackVo.setCompleteAmount(request.getParameter("completeAmount"));//担保完成金额（分）
        paymentCallbackVo.setBillDate(request.getParameter("billDate"));//订单时间，格式yyyy-MM-dd
        paymentCallbackVo.setCreateTime(request.getParameter("createTime"));//账单创建时间，格式yyyy-MM-dd HH:mm:ss
        paymentCallbackVo.setSign(request.getParameter("sign"));//签名
        paymentCallbackVo.setExtraBuyerInfo(request.getParameter("extraBuyerInfo"));//用户额外信息

        PrintWriter printWriter;
        response.setCharacterEncoding("UTF-8");
        try {
            printWriter = response.getWriter();
            printWriter.write("success");
            printWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return paymentCallbackVo.toString();
    }

    /**
     * 银联二维码更新
     * */
    public static String unionPayQRCodeRenew(UnionPayQRCodeRequest unionPayQRCodeRequest){

        unionPayQRCodeRequest.setRequestTimestamp(dateToStamp());

        String sign = "instMid=" + unionPayQRCodeRequest.getInstMid();
        sign = sign + "&mid=" + unionPayQRCodeRequest.getMid();
        sign = sign + "&msgSrc=" + unionPayQRCodeRequest.getMsgSrc();
        sign = sign + "&msgType=" + unionPayQRCodeRequest.getMsgType();
        sign = sign + "&qrCodeId=" + unionPayQRCodeRequest.getQrCodeId();
        sign = sign + "&requestTimestamp=" + unionPayQRCodeRequest.getRequestTimestamp();
        sign = sign + "&signType=" + unionPayQRCodeRequest.getSignType();
        sign = sign + "&tid=" + unionPayQRCodeRequest.getTid();
        sign = sign + "&totalAmount=" + unionPayQRCodeRequest.getTotalAmount();
        sign = sign + "8Jj7h5S7eXyC4Y48S7xC2eWbxkdtmaD2d3xa68z7pTekE8Wz";

        String sha = DigestUtils.md5Hex(sign);
        unionPayQRCodeRequest.setSign(sha);

        SortedMap<String, Object> params = new TreeMap<>();
        params.put("msgType", unionPayQRCodeRequest.getMsgType());
        params.put("msgSrc", unionPayQRCodeRequest.getMsgSrc());
        params.put("mid", unionPayQRCodeRequest.getMid());
        params.put("tid", unionPayQRCodeRequest.getTid());
        params.put("instMid", unionPayQRCodeRequest.getInstMid());
        params.put("totalAmount", unionPayQRCodeRequest.getTotalAmount());
        params.put("requestTimestamp", unionPayQRCodeRequest.getRequestTimestamp());
        params.put("qrCodeId", unionPayQRCodeRequest.getQrCodeId());
        params.put("signType", unionPayQRCodeRequest.getSignType());
        params.put("sign", unionPayQRCodeRequest.getSign());

        String postJson = HttpClientUtil.doPostJson(url, JSON.toJSONString(params));
        return postJson;
    }

    /**
     * 银联二维码关闭
     * */
    public static String unionPayQRCodeClosure(UnionPayQRCodeRequest unionPayQRCodeRequest){

        unionPayQRCodeRequest.setRequestTimestamp(dateToStamp());

        String sign = "instMid=" + unionPayQRCodeRequest.getInstMid();
        sign = sign + "&mid=" + unionPayQRCodeRequest.getMid();
        sign = sign + "&msgSrc=" + unionPayQRCodeRequest.getMsgSrc();
        sign = sign + "&msgType=" + unionPayQRCodeRequest.getMsgType();
        sign = sign + "&qrCodeId=" + unionPayQRCodeRequest.getQrCodeId();
        sign = sign + "&requestTimestamp=" + unionPayQRCodeRequest.getRequestTimestamp();
        sign = sign + "&signType=" + unionPayQRCodeRequest.getSignType();
        sign = sign + "&tid=" + unionPayQRCodeRequest.getTid();
        sign = sign + "8Jj7h5S7eXyC4Y48S7xC2eWbxkdtmaD2d3xa68z7pTekE8Wz";

        String sha = DigestUtils.md5Hex(sign);
        unionPayQRCodeRequest.setSign(sha);

        SortedMap<String, Object> params = new TreeMap<>();
        params.put("msgType", unionPayQRCodeRequest.getMsgType());
        params.put("msgSrc", unionPayQRCodeRequest.getMsgSrc());
        params.put("mid", unionPayQRCodeRequest.getMid());
        params.put("tid", unionPayQRCodeRequest.getTid());
        params.put("instMid", unionPayQRCodeRequest.getInstMid());
        params.put("requestTimestamp", unionPayQRCodeRequest.getRequestTimestamp());
        params.put("qrCodeId", unionPayQRCodeRequest.getQrCodeId());
        params.put("signType", unionPayQRCodeRequest.getSignType());
        params.put("sign", unionPayQRCodeRequest.getSign());

        String postJson = HttpClientUtil.doPostJson(url, JSON.toJSONString(params));
        return postJson;
    }

    /**
     * 银联账单状态查询
     * */
    public static UnionPayQRCodeResponse unionPayBillingStatusQuery(UnionPayQRCodeRequest unionPayQRCodeRequest){
        unionPayQRCodeRequest.setMsgType("bills.query");
        fillQRCodeInfo(unionPayQRCodeRequest);

        String sign = "billDate=" + unionPayQRCodeRequest.getBillDate();
        sign = sign + "&billNo=" + unionPayQRCodeRequest.getBillNo();
        sign = sign + "&instMid=" + unionPayQRCodeRequest.getInstMid();
        sign = sign + "&mid=" + unionPayQRCodeRequest.getMid();
        sign = sign + "&msgSrc=" + unionPayQRCodeRequest.getMsgSrc();
        sign = sign + "&msgType=" + unionPayQRCodeRequest.getMsgType();
        sign = sign + "&requestTimestamp=" + unionPayQRCodeRequest.getRequestTimestamp();
        sign = sign + "&signType=" + unionPayQRCodeRequest.getSignType();
        sign = sign + "&tid=" + unionPayQRCodeRequest.getTid();
        sign = sign + "8Jj7h5S7eXyC4Y48S7xC2eWbxkdtmaD2d3xa68z7pTekE8Wz";

        String sha = DigestUtils.md5Hex(sign);
        unionPayQRCodeRequest.setSign(sha);

        SortedMap<String, Object> params = new TreeMap<>();
        params.put("msgType", unionPayQRCodeRequest.getMsgType());
        params.put("billNo", unionPayQRCodeRequest.getBillNo());
        params.put("billDate", unionPayQRCodeRequest.getBillDate());
        params.put("msgSrc", unionPayQRCodeRequest.getMsgSrc());
        params.put("mid", unionPayQRCodeRequest.getMid());
        params.put("tid", unionPayQRCodeRequest.getTid());
        params.put("instMid", unionPayQRCodeRequest.getInstMid());
        params.put("requestTimestamp", unionPayQRCodeRequest.getRequestTimestamp());
        params.put("signType", unionPayQRCodeRequest.getSignType());
        params.put("sign", unionPayQRCodeRequest.getSign());

        String postJson = HttpClientUtil.doPostJson(url, JSON.toJSONString(params));
        UnionPayQRCodeResponse unionPayQRCodeResponse = JSON.parseObject(postJson, UnionPayQRCodeResponse.class);
        return unionPayQRCodeResponse;
    }

    /**
     * 银联退款
     * */
    public static UnionPayQRCodeResponse unionPayRefund(UnionPayQRCodeRequest unionPayQRCodeRequest){

        unionPayQRCodeRequest.setMsgType("bills.refund");
        fillQRCodeInfo(unionPayQRCodeRequest);
        String sign = "billDate=" + unionPayQRCodeRequest.getBillDate();
        sign = sign + "&billNo=" + unionPayQRCodeRequest.getBillNo();
        sign = sign + "&instMid=" + unionPayQRCodeRequest.getInstMid();
        sign = sign + "&mid=" + unionPayQRCodeRequest.getMid();
        sign = sign + "&msgSrc=" + unionPayQRCodeRequest.getMsgSrc();
        sign = sign + "&msgType=" + unionPayQRCodeRequest.getMsgType();
        sign = sign + "&notifyUrl=" + unionPayQRCodeRequest.getNotifyUrl();
        sign = sign + "&refundAmount=" + unionPayQRCodeRequest.getRefundAmount();
        sign = sign + "&requestTimestamp=" + unionPayQRCodeRequest.getRequestTimestamp();
        sign = sign + "&signType=" + unionPayQRCodeRequest.getSignType();
        sign = sign + "&tid=" + unionPayQRCodeRequest.getTid();
        sign = sign + "8Jj7h5S7eXyC4Y48S7xC2eWbxkdtmaD2d3xa68z7pTekE8Wz";

        String sha = DigestUtils.md5Hex(sign);
        unionPayQRCodeRequest.setSign(sha);

        SortedMap<String, Object> params = new TreeMap<>();
        params.put("msgType", unionPayQRCodeRequest.getMsgType());
        params.put("billNo", unionPayQRCodeRequest.getBillNo());
        params.put("billDate", unionPayQRCodeRequest.getBillDate());
        params.put("msgSrc", unionPayQRCodeRequest.getMsgSrc());
        params.put("refundAmount", unionPayQRCodeRequest.getRefundAmount());
        params.put("mid", unionPayQRCodeRequest.getMid());
        params.put("tid", unionPayQRCodeRequest.getTid());
        params.put("instMid", unionPayQRCodeRequest.getInstMid());
        params.put("requestTimestamp", unionPayQRCodeRequest.getRequestTimestamp());
        params.put("signType", unionPayQRCodeRequest.getSignType());
        params.put("sign", unionPayQRCodeRequest.getSign());
        params.put("notifyUrl", unionPayQRCodeRequest.getNotifyUrl());

        String postJson = HttpClientUtil.doPostJson(url, JSON.toJSONString(params));
        UnionPayQRCodeResponse unionPayQRCodeResponse = JSON.parseObject(postJson, UnionPayQRCodeResponse.class);
        return unionPayQRCodeResponse;
    }

//    /**
//     *  填充测试环境二维码支付基础信息
//     * @param unionPayQRCodeRequest
//     */
//    private static void fillQRCodeInfo(UnionPayQRCodeRequest unionPayQRCodeRequest)
//    {
//        unionPayQRCodeRequest.setMsgSrc("WWW.TEST.COM");
//        unionPayQRCodeRequest.setMid("898340149000005");
//        unionPayQRCodeRequest.setTid("88880001");
//        unionPayQRCodeRequest.setInstMid("QRPAYDEFAULT");
//        unionPayQRCodeRequest.setSignType("SHA256");
//        unionPayQRCodeRequest.setRequestTimestamp(dateToStamp());
//        unionPayQRCodeRequest.setBillDate(dateToStamp());
//    }

//        <ConfigName>UnionPayCSanB1001</ConfigName>
//    <MiniType>CSanB</MiniType>
//    <AppId>898120045110575</AppId>  <!--#商户号 mid=898340149000005-->
//    <Tid>01490036</Tid>
//   <SignType>MD5</SignType>
// <VerifyPublicKey>8Jj7h5S7eXyC4Y48S7xC2eWbxkdtmaD2d3xa68z7pTekE8Wz</VerifyPublicKey>
    private static void fillQRCodeInfo(UnionPayQRCodeRequest unionPayQRCodeRequest)
    {
        unionPayQRCodeRequest.setMsgSrc("WWW.BJJSSJS.COM");
        unionPayQRCodeRequest.setMid("898120045110575");
        unionPayQRCodeRequest.setTid("01490036");
        unionPayQRCodeRequest.setInstMid("QRPAYDEFAULT");
        unionPayQRCodeRequest.setSignType("MD5");
        unionPayQRCodeRequest.setRequestTimestamp(dateToStamp());
        unionPayQRCodeRequest.setBillDate(dateToStamp());
    }


    public static void main(String[] args) throws Exception {
        UnionPayController unionPayController = new UnionPayController();

        /**
         * {
         *     "msgType": "bills.getQRCode",
         *     "billNo": "3194201609234113339074548947",
         *     "requestTimestamp": "2022-03-03 09:33:05",
         *     "msgSrc": "WWW.TEST.COM",
         *     "sign": "2b4bc1cb8564f1dbc9869778c2338bc2862bdfd8887a611b1155c4bb0a5095ca",
         *     "signType" : "SHA256",
         *     "mid": "898340149000005",
         *     "billDate": "2022-03-03 10:15:18",
         *     "tid": "88880001",
         *     "instMid": "QRPAYDEFAULT",
         *     "totalAmount": "1"
         * }
         * */

        /** 银联二维码获取 */
        UnionPayQRCodeRequest unionPayQRCodeRequest = new UnionPayQRCodeRequest();
        unionPayQRCodeRequest.setMsgSrc("WWW.TEST.COM");
        unionPayQRCodeRequest.setMsgType("bills.getQRCode");
        unionPayQRCodeRequest.setMid("898340149000005");
        unionPayQRCodeRequest.setTid("88880001");
        unionPayQRCodeRequest.setInstMid("QRPAYDEFAULT");
        unionPayQRCodeRequest.setBillNo("3194201609234113339074541116");
        unionPayQRCodeRequest.setSignType("SHA256");
        unionPayQRCodeRequest.setTotalAmount("1");

        String postJson = null;
        try {
//            postJson = unionPayController.unionPayQRCodePay(unionPayQRCodeRequest);
        } catch (Exception e){
//            throw new Exception(e.getMessage());
        }

        System.out.println(postJson);

        /** 银联二维码更新 */
//        UnionPayQRCodeRequest unionPayQRCodeRequest = new UnionPayQRCodeRequest();
//        unionPayQRCodeRequest.setMsgSrc("WWW.TEST.COM");
//        unionPayQRCodeRequest.setMsgType("bills.updateQRCode");
//        unionPayQRCodeRequest.setMid("898340149000005");
//        unionPayQRCodeRequest.setTid("88880001");
//        unionPayQRCodeRequest.setInstMid("QRPAYDEFAULT");
//        unionPayQRCodeRequest.setQrCodeId("31942203038454512143610756");
//        unionPayQRCodeRequest.setSignType("SHA256");
//        unionPayQRCodeRequest.setTotalAmount("1");
//        String postJson = unionPayController.unionPayQRCodeRenew(unionPayQRCodeRequest);
//        System.out.println(postJson);

        /** 银联二维码关闭 */
//        UnionPayQRCodeRequest unionPayQRCodeRequest = new UnionPayQRCodeRequest();
//        unionPayQRCodeRequest.setMsgSrc("WWW.TEST.COM");
//        unionPayQRCodeRequest.setMsgType("bills.closeQRCode");
//        unionPayQRCodeRequest.setMid("898340149000005");
//        unionPayQRCodeRequest.setTid("88880001");
//        unionPayQRCodeRequest.setInstMid("QRPAYDEFAULT");
//        unionPayQRCodeRequest.setQrCodeId("31942203038454512143610756");
//        unionPayQRCodeRequest.setSignType("SHA256");
//        String postJson = unionPayController.unionPayQRCodeClosure(unionPayQRCodeRequest);
//        System.out.println(postJson);

        /** 银联账单状态查询 */
//        UnionPayQRCodeRequest unionPayQRCodeRequest = new UnionPayQRCodeRequest();
//        unionPayQRCodeRequest.setMsgSrc("WWW.TEST.COM");
//        unionPayQRCodeRequest.setMsgType("bills.query");
//        unionPayQRCodeRequest.setMid("898340149000005");
//        unionPayQRCodeRequest.setTid("88880001");
//        unionPayQRCodeRequest.setInstMid("QRPAYDEFAULT");
//        unionPayQRCodeRequest.setBillNo("3194201609234113339074541112");
//        unionPayQRCodeRequest.setSignType("SHA256");
//        String postJson = unionPayController.unionPayBillingStatusQuery(unionPayQRCodeRequest);
//        System.out.println(postJson);

        /** 银联退款 */
//        UnionPayQRCodeRequest unionPayQRCodeRequest = new UnionPayQRCodeRequest();
//        unionPayQRCodeRequest.setMsgSrc("WWW.TEST.COM");
//        unionPayQRCodeRequest.setMsgType("bills.refund");
//        unionPayQRCodeRequest.setMid("898340149000005");
//        unionPayQRCodeRequest.setTid("88880001");
//        unionPayQRCodeRequest.setInstMid("QRPAYDEFAULT");
//        unionPayQRCodeRequest.setBillNo("3194201609234113339074541111");
//        unionPayQRCodeRequest.setSignType("SHA256");
//        unionPayQRCodeRequest.setRefundAmount("1");
//        String postJson = unionPayController.unionPayRefund(unionPayQRCodeRequest);
//        System.out.println(postJson);
    }

    /**
     * 获取时间戳yyyy-MM-dd HH:mm:ss
     * */
    public static String dateToStamp() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String res;
        Date time = new Date();
        String s = simpleDateFormat.format(time);
        Date date = null;
        try {
            date = simpleDateFormat.parse(s);
        } catch (Exception e){
            System.out.println("时间转换失败");
        }

        long ts = date.getTime();
        res = String.valueOf(ts);
        return res;
    }

    /**
     * 获取时间戳yyyy-MM-dd
     * */
    public static String timeToStamp() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String res;
        Date time = new Date();
        String s = simpleDateFormat.format(time);
        Date date = null;
        try {
            date = simpleDateFormat.parse(s);
        } catch (Exception e){
            System.out.println("时间转换失败");
        }

        long ts = date.getTime();
        res = String.valueOf(ts);
        return res;
    }

    /**
     * SHA256加密
     * */
    public static String SHA(final String strText){
        //返回值
        String strResult = null;

        String strType = "SHA-256";

        //是否是有效字符串
        if (strText != null && strText.length() > 0){
            try {
                //SHA开始加密
                //创建加密对象
                MessageDigest messageDigest = MessageDigest.getInstance(strType);
                //传入要加密的字符串
                messageDigest.update(strText.getBytes());
                //得到byte类型结果
                byte byteBudder[] = messageDigest.digest();

                //将byte转换成string
                StringBuffer strHexString = new StringBuffer();
                //遍历byte buffer
                for (int i = 0 ; i < byteBudder.length ; i++){
                    String hex = Integer.toHexString(0xff & byteBudder[i]);
                    if (hex.length() == 1){
                        strHexString.append('0');
                    }
                    strHexString.append(hex);
                }
                //得到返回结果
                strResult = strHexString.toString();
            } catch (NoSuchAlgorithmException e){
                e.printStackTrace();
            }
        }

        return strResult;
    }

}
